package com.ten.course.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.ten.common.core.entity.EduCourse;
import com.ten.common.core.entity.EduSubject;
import com.ten.common.core.vo.Result;
import com.ten.course.dao.CourseListDao;
import com.ten.course.dao.CourseSubjectDao;
import com.ten.course.service.CourseSubjectService;
import com.ten.course.utils.CourseUtil;
import com.ten.course.vo.CourseSubjectVo;
import com.ten.course.vo.SubjectInsertVo;
import lombok.extern.java.Log;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.util.StringUtils;
import java.util.ArrayList;
import java.util.List;

/**
 * @author ：张成（3092211427@qq.com）
 * @date ：Created in 2022/12/7 20:18
 * @description：
 * @modified By：
 * @version:
 */
@Service
@Log
public class CourseSubjectServiceImpl extends ServiceImpl<CourseSubjectDao, EduSubject> implements CourseSubjectService {
    @Autowired
    private CourseSubjectDao courseSubjectDao;

    @Autowired
    private CourseSubjectService courseSubjectService;

    @Autowired
    private CourseListDao courseListDao;

    @Override
    public Result<Page<EduSubject>> findSubject(Integer pageCurrent, Integer pageSize, CourseSubjectVo courseSubjectVo) {
        Page<EduSubject> page = new Page<>(pageCurrent, pageSize);
        QueryWrapper<EduSubject> queryWrapper = new QueryWrapper<>();
        if (StringUtils.hasText(courseSubjectVo.getStatusId())) {
            queryWrapper.eq("status_id", courseSubjectVo.getStatusId());
        }
        if (StringUtils.hasText(courseSubjectVo.getTitle())) {
            queryWrapper.like("title", courseSubjectVo.getTitle());
        }
        List<EduSubject> list = courseSubjectDao.selectList(queryWrapper);
        queryWrapper.eq("parent_id", "0");
        Page<EduSubject> page2 = courseSubjectDao.selectPage(page, queryWrapper);
        for (EduSubject record : page2.getRecords()) {
            CourseUtil.setTreeChildren(record, list);
        }
        return new Result<>(200, "查询成功", page2);
    }

    /**
     * 根据课程分类id和课程分类父id修改用户的状态
     *
     * @param eduSubject 课程分类实体类，用于接收id，父id，和statusId
     * @return
     */
    @Override
    public Result changeStatusId(EduSubject eduSubject) {
        EduSubject eduSubject1 = courseSubjectDao.selectById(eduSubject.getParentId());
        if (eduSubject1 != null) {
            if ("0".equals(eduSubject1.getStatusId())) {
                return new Result(500, "上级处于禁用状态，该子分类状态需要与上级保持一致");
            }
        }
        List<EduSubject> list = getAllEduSubjectsFromSubject(eduSubject);
        for (EduSubject subject : list) {
            subject.setStatusId(eduSubject.getStatusId());
        }
        boolean b = courseSubjectService.updateBatchById(list);
        if (b) {
            return new Result(200, "更新成功");
        }
        return new Result(500, "更新失败");
    }

    /**
     * 根据插入Vo类中的条件进行课程分类的添加
     *
     * @param subjectInsertVo 插入条件字段Vo
     * @return
     */
    @Override
    public Result insertSubject(SubjectInsertVo subjectInsertVo) {
        //1.需要插入到具体哪个分类  根据传入的当前行的id插入到当前行下的分类
        //2.需要在哪些相关表中插入数据   只需要在分类表中插入数据
        EduSubject eduSubject = new EduSubject();
        List<EduSubject> eduSubjects = courseSubjectDao.selectList(null);
        for (EduSubject subject : eduSubjects) {
            //equalsIgnoreCase比较时不区分大小写
            if (subject.getTitle().equalsIgnoreCase(subjectInsertVo.getTitle())) {
                return new Result(500, "你所添加的分类已经存在，请换一个其他的");
            } else {
                eduSubject.setTitle(subjectInsertVo.getTitle());
            }
        }
        eduSubject.setParentId(subjectInsertVo.getId());
        eduSubject.setStatusId("1");
        eduSubject.setRemark(subjectInsertVo.getRemark());
        EduSubject eduSubject1 = courseSubjectDao.selectById(subjectInsertVo.getId());
        if (eduSubject1 != null) {
            for (int i = 0; i < 10; i++) {
                if (eduSubject1.getSort() == i) {
                    eduSubject.setSort(i + 1);
                }
            }
        } else {
            eduSubject.setSort(0);
        }
        int insert = courseSubjectDao.insert(eduSubject);
        if (insert > 0) {
            return new Result(200, "添加分类成功");
        }
        return new Result(500, "添加分类失败");
    }

    /**
     * 根据课程分类id删除课程分类
     *
     * @param eduSubject 课程类，用于接收课程id
     * @return
     */
    @Override
    public Result deleteSubject(EduSubject eduSubject) {
        //1.根据课程分类id删除相关分类   需要删除哪些分类，这个要明确
        //2.如果删除的分类下有子分类，那么其下的分类也要进行删除
        EduSubject eduSubject1 = courseSubjectDao.selectById(eduSubject.getId());
        //如果该课程分类或者该分类下的某个分类有课程存在，不允许进行删除
        boolean b = checkExists(eduSubject1);
        if (b) {
            return new Result(502, "该分类或该分类下有课程存在，请先删除相关课程");
        }
        List<EduSubject> list = getAllEduSubjectsFromSubject(eduSubject1);
        int i = courseSubjectDao.deleteBatchIds(list);
        if (i > 0) {
            return new Result(200, "删除成功");
        }
        return new Result(500, "删除失败");
    }

    private boolean checkExists(EduSubject eduSubject1) {
        //用于判断分类下是否具有课程
        int flag = 0;
        //获取eduSubject1层级下的所有EduSubject
        List<EduSubject> allEduSubjectsFromSubject = getAllEduSubjectsFromSubject(eduSubject1);
        for (EduSubject eduSubject : allEduSubjectsFromSubject) {
            List<EduCourse> eduCourses = courseListDao.selectList(new QueryWrapper<EduCourse>()
                    .eq("subject_id", eduSubject.getId()));
            if (!eduCourses.isEmpty()) {
                flag++;
            }
        }
        return flag > 0;
    }

    /**
     * 根据接收的参数来对eduSubject进行修改
     *
     * @param eduSubject 用于接收需要修改的数据
     * @return
     */
    @Override
    public Result updateSubject(EduSubject eduSubject) {
        int i = courseSubjectDao.updateById(eduSubject);
        if (i > 0) {
            return new Result(200, "修改成功");
        }
        return new Result(500, "修改失败");
    }
    /*************************客户端service*********************/

    /**
     * 根据pid查询父亲的id，返回父亲的id到前端
     *
     * @param pid
     * @return
     */
    @Override
    public Result<String> findPidById(String pid) {
        EduSubject eduSubject = courseSubjectDao.selectById(pid);
        if (eduSubject != null) {
            if (!"0".equals(eduSubject.getParentId())) {
                EduSubject subjectParent = courseSubjectDao.selectById(eduSubject.getParentId());
                return new Result<>(200, "查询成功", subjectParent.getId());
            } else if ("0".equals(eduSubject.getParentId())) {
                return new Result<>(200, "查询成功", "0");
            }
        }
        return new Result<>(500, "查询失败");
    }

    /**
     * 获取课程分类信息
     *
     * @return
     */
    @Override
    public Result<List<EduSubject>> findSubjectByStatus() {//findSubjectByStatus
        QueryWrapper<EduSubject> wrapper = new QueryWrapper<>();
        //查询出statusId为1的课程分类
        wrapper.eq("status_id", "1");
        List<EduSubject> list = courseSubjectDao.selectList(wrapper);
        List<EduSubject> treeEduSubjectList = CourseUtil.fromEduSubjectListToTreeEduSubjectList(list);
        return new Result<>(200, "查询成功", treeEduSubjectList);
    }

    /**
     * 根据某个eduSubject获取这个eduSubject以及自己包括的层级中的eduSubject
     *
     * @param eduSubject 某个eduSubject
     * @return List<EduSubject>
     */
    private List<EduSubject> getAllEduSubjectsFromSubject(EduSubject eduSubject) {
        List<EduSubject> list = courseSubjectDao.selectList(null);
        List<EduSubject> treeEduSubjectList = CourseUtil.fromEduSubjectListToTreeEduSubjectList(list);
        List<EduSubject> changeList = new ArrayList<>();
        //遍历树形结构，将一级层级作为参数放入setChildrenToList方法中进而获取eduSubject以及自己包括的层级中的eduSubject
        for (EduSubject subject : treeEduSubjectList) {
            changeList = setChildrenToList(subject, eduSubject, changeList);
        }
        return changeList;
    }

    /**
     * 判断自己在哪个树形结构下，并获取自己和自己的孩子到集合中
     *
     * @param subject    一级层级
     * @param eduSubject 某个课程分类类
     * @param changeList 返回该类及其子类的list集合
     * @return List<EduSubject>
     */
    private List<EduSubject> setChildrenToList(EduSubject subject, EduSubject eduSubject, List<EduSubject> changeList) {
        //如果是选中的是最上面的层级（一级层级），则获取最上面以及子类下的所有到changeList中
        if (eduSubject.getId().equals(subject.getId())) {
            changeList.add(subject);
            //添加子及其下级到集合中
            changeList = getAllSubjects(changeList, subject);
            //如果是除了最上面一级的其他层级，则要根据eduSubject.getId()与树形结构的孩子进行一级一级的比较
        } else if (subject.getChildren() != null) {
            for (EduSubject child : subject.getChildren()) {
                if (eduSubject.getId().equals(child.getId())) {
                    changeList.add(child);
                    changeList = getAllSubjects(changeList, child);
                } else {
                    //不符合条件，则再次进行递归调用
                    changeList = setChildrenToList(child, eduSubject, changeList);
                }
            }
        }
        return changeList;
    }

    /**
     * 使用递归判断参数中subject是否还有孩子，如果有则进行递归
     *
     * @param changeList 返回该类及其子类的list集合
     * @param subject    用于判断参数中subject是否还有孩子的subject类
     * @return List<EduSubject>
     */
    private List<EduSubject> getAllSubjects(List<EduSubject> changeList, EduSubject subject) {
        if (subject.getChildren() != null) {
            for (EduSubject child : subject.getChildren()) {
                changeList.add(child);
                changeList = getAllSubjects(changeList, child);
            }
        }
        return changeList;
    }

    /**
     * 获取所有的课程分类列表
     *
     * @return
     */
    @Override
    public Result<List<EduSubject>> getAllMenu() {
        //获取所有的课程分类列表
        return this.findSubjectByStatus();
    }
}